package com.mdd.front.controller.zdjd;

import com.google.common.util.concurrent.AtomicDouble;
import com.mdd.common.aop.NotLogin;
import com.mdd.common.aop.NotPower;
import com.mdd.common.entity.yangyangLeadingEnterprise.common.JsonReturn;
import com.mdd.common.entity.zdjd.*;
import com.mdd.common.entity.zdjd.dto.*;
import com.mdd.common.entity.zdjd.param.DeviceFeedbackDataParam;
import com.mdd.common.util.ToolUtils;
import com.mdd.common.util.webSocket.WebSocketServer;
//import com.mdd.front.service.zdjd.ITZdjdAgentService;
import com.mdd.front.service.zdjd.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.time.YearMonth;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@ApiIgnore
@RestController
@RequestMapping("/api/ws")
public class WebSocketController {

    @Resource
    ITZdjdAgentService agentService;

    @Resource
    ITZdjdDeviceService deviceService;

    @Resource
    ITZdjdDeviceDataService deviceDataService;

    @Resource
    ITZdjdRechargeRecordService rechargeRecordService;

    @Resource
    ITZdjdDeviceStateRecordService deviceStateRecordService;

    @NotPower
    @NotLogin
    @RequestMapping("/test111")
    public void test111(){
        ScreenDataDTO dto = new ScreenDataDTO();
        //设备状态比例表
        DeviceStatusDTO deviceStatusDTO1 = new DeviceStatusDTO();
        deviceStatusDTO1.setStatusName("在线设备数");
        deviceStatusDTO1.setDeviceAmount(10);
        deviceStatusDTO1.setPercentage(0.1);
        DeviceStatusDTO deviceStatusDTO2 = new DeviceStatusDTO();
        deviceStatusDTO2.setStatusName("运行设备数");
        deviceStatusDTO2.setDeviceAmount(10);
        deviceStatusDTO2.setPercentage(0.2);
        DeviceStatusDTO deviceStatusDTO3 = new DeviceStatusDTO();
        deviceStatusDTO3.setStatusName("离线设备数");
        deviceStatusDTO3.setDeviceAmount(10);
        deviceStatusDTO3.setPercentage(0.13);
        List<DeviceStatusDTO> deviceStatusDTOList = Arrays.asList(deviceStatusDTO1,deviceStatusDTO2,deviceStatusDTO3);
        dto.setDeviceStatusDTOList(deviceStatusDTOList);
        dto.setAgentDeviceAmount(100);
        dto.setAgentTodayEcharge(1530.28);
        dto.setAgentEstimatedUsage(1000.00);
        dto.setAgentActualUsage(523.00);

        AgentRankDTO agentRankDTO1 = new AgentRankDTO();
        agentRankDTO1.setAgentName("代理商001");
        agentRankDTO1.setAgentDeviceTotalAmount(500);
        AgentRankDTO agentRankDTO2 = new AgentRankDTO();
        agentRankDTO2.setAgentName("代理商002");
        agentRankDTO2.setAgentDeviceTotalAmount(400);
        List<AgentRankDTO> agentRankDTOList=Arrays.asList(agentRankDTO1,agentRankDTO2);
        dto.setAgentRankDTOList(agentRankDTOList);

        dto.setTodayWorkDeviceAmount(100562);
        dto.setTodayFuelConsumption(56242.23);
        dto.setTodayEstimatedIncome(562355.89);
        dto.setMonthFuelConsumption(89536.53);

        List<DeviceActivationDTO> deviceActivationDTOList=Arrays.asList(DeviceActivationDTO.create(1,10),
                DeviceActivationDTO.create(2,1150),
                DeviceActivationDTO.create(3,100),
                DeviceActivationDTO.create(4,120),
                DeviceActivationDTO.create(5,1300),
                DeviceActivationDTO.create(6,133),
                DeviceActivationDTO.create(7,180),
                DeviceActivationDTO.create(8,150),
                DeviceActivationDTO.create(9,104),
                DeviceActivationDTO.create(10,102),
                DeviceActivationDTO.create(11,120),
                DeviceActivationDTO.create(12,2215));
        dto.setDeviceActivationDTOList(deviceActivationDTOList);

        List<DeviceOilConsumption> deviceOilConsumptionList=Arrays.asList(DeviceOilConsumption.convert("1",1.2),
                DeviceOilConsumption.convert("2",1152.2),
                DeviceOilConsumption.convert("3",145.2),
                DeviceOilConsumption.convert("4",112.2),
                DeviceOilConsumption.convert("5",18.2),
                DeviceOilConsumption.convert("6",156.2),
                DeviceOilConsumption.convert("7",127.2),
                DeviceOilConsumption.convert("8",192.2),
                DeviceOilConsumption.convert("9",163.2),
                DeviceOilConsumption.convert("10",125.2),
                DeviceOilConsumption.convert("11",14.2),
                DeviceOilConsumption.convert("12",189.2));
        dto.setDeviceOilConsumptionList(deviceOilConsumptionList);

        dto.setSingleDeviceAmount(1562);
        dto.setDoubleDeviceAmount(1252);
        dto.setAverageDeviceConsumption(445.26);
        dto.setTodayTotalConsumption(458956.69);

        WebSocketServer.sendInfo( JsonReturn.success().put("screenDataDTO",dto).toJsonStr(),"zhongdunjinda");
    }

    /**
     * 设备回传数据
     * @param param
     * @return
     */
    @NotPower
    @NotLogin
    @PostMapping("/deviceFeedbackData")
    public String deviceFeedbackData(@RequestBody DeviceFeedbackDataParam param){
        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        String deviceName = param.getDeviceName();
        String deviceCode = param.getDeviceCode();
        Integer status = param.getStatus();
        Integer type = param.getType();

        String agentKey = param.getAgentKey();
        String agentName = param.getAgentName();
        String agentIdCard = param.getAgentIdCard();
        String agentPhone = param.getAgentPhone();

        BigDecimal oil = param.getOil();
        BigDecimal runTime = param.getRunTime();

        //代理商
        TZdjdAgent agent = new TZdjdAgent();
        if(agentKey!=null && !agentKey.isEmpty()){
            agent = agentService.selectAgentByKey(agentKey);
        }else{
            if(agentName==null || agentName.isEmpty() || agentIdCard==null || agentIdCard.isEmpty() || agentPhone==null || agentPhone.isEmpty()){
                return JsonReturn.fail("参数错误",40001).toJsonStr();
            }
            agent.setName(param.getAgentName());
            agent.setPhone(param.getAgentPhone());
            agent.setIdCard(param.getAgentIdCard());
            agent.setAgentKey(ToolUtils.randomString(16));
            agent.setDeviceTotalAmount(0);
            agent.setEchargeTotalAmount(0L);
            agent.setPromotionTotalAmount(0);
            agent.setCreateTime(now);
            agent.setUpdateTime(now);
            agentService.insertAgent(agent);
        }
        //设备
        TZdjdDevice device= new TZdjdDevice();
        if(deviceCode!=null && !deviceCode.isEmpty()){
            device=deviceService.selectDeviceByCode(param.getDeviceCode());
        }else{
            if(deviceName==null || deviceName.isEmpty() || type==null){
                return JsonReturn.fail("参数错误",40001).toJsonStr();
            }
            device.setName(deviceName);
            device.setDeviceCode(ToolUtils.randomString(16));
            device.setStatus(status);
            device.setType(type);
            device.setCreateTime(now);
            device.setYear(String.valueOf(calendar.get(Calendar.YEAR)));
            device.setMonth(String.valueOf(calendar.get(Calendar.MONTH)+1));
            device.setDay(String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));
            device.setUpdateTime(now);
            device.setRunTotalTime(0L);
            device.setTotalEnergyConsumption(0L);
            device.setAgentId(agent.getId());
            device.setAgentName(agent.getName());
            deviceService.insertDevice(device);
        }
        //设备数据
        if(oil==null || runTime==null){
            return JsonReturn.fail("参数错误",40001).toJsonStr();
        }
        TZdjdDeviceData deviceData = new TZdjdDeviceData();
        deviceData.setEnergyConsumption(String.valueOf(oil));
        deviceData.setRunTime(runTime.longValue());
        deviceData.setCreateTime(now);
        deviceData.setYear(String.valueOf(calendar.get(Calendar.YEAR)));
        deviceData.setMonth(String.valueOf(calendar.get(Calendar.MONTH)+1));
        deviceData.setDay(String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)));
        deviceData.setUpdateTime(now);

        deviceData.setDeviceId(device.getId());
        deviceData.setDeviceCode(device.getDeviceCode());
        deviceDataService.insertDeviceData(deviceData);





        return JsonReturn.fail().toJsonStr();
    }


    /**
     * 中控数据大屏
     *
     * 代理商预估使用量
     * param type 设备开通展示表：1:按照年查询；2：按照月查询
     * @return
     */
    public ScreenDataDTO selectScreenData(Integer type,Integer deviceActivationYear, Integer deviceActivationMonth,Integer OilYear){
        Calendar calendar = Calendar.getInstance();
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH)+1;
        Integer day = calendar.get(Calendar.DAY_OF_MONTH);
        if(type==null){
            type=2;
        }
        if(deviceActivationYear==null){
            deviceActivationYear=year;
        }
       if(type==2){
            if(deviceActivationMonth==null){
                deviceActivationMonth=month;
            }
        }
        if(OilYear==null){
            OilYear=year;
        }
        ScreenDataDTO dto = new ScreenDataDTO();
        List<TZdjdDevice> deviceList=deviceService.selectAll();
        List<TZdjdAgent> agentList=agentService.selectAll();
        List<TZdjdDeviceStateRecord> deviceStateRecordList=deviceStateRecordService.selectListByYearMonthDay(year,month,null);

        //设备状态比例列表
        HashMap<Integer, Integer> deviceStatusDTOMap = new HashMap<>();
        //设备开通数据统计列表
        Integer finalType = type;
        Integer finalDeviceActivationYear = deviceActivationYear;
        Integer finalDeviceActivationMonth = deviceActivationMonth;
        HashMap<Integer, Integer> deviceActivationDTOMap = new HashMap<>();
        //单双灶数量
        AtomicInteger singleDeviceAmount = new AtomicInteger(0);
        AtomicInteger doubleDeviceAmount = new AtomicInteger(0);
        deviceList.parallelStream().forEach(device -> {
            Integer deviceType = device.getType();
            Integer status = device.getStatus();
            Integer deviceYear = Integer.valueOf(device.getYear());
            Integer deviceMonth = Integer.valueOf(device.getMonth());
            Integer deviceDay = Integer.valueOf(device.getDay());
            if(deviceStatusDTOMap.containsKey(status)){
                deviceStatusDTOMap.put(status,Optional.ofNullable(deviceStatusDTOMap.get(status)).orElse(0)+1);
            }else{
                deviceStatusDTOMap.put(status,1);
            }
            if(finalType ==1 && Objects.equals(finalDeviceActivationYear,deviceYear)){
                if(deviceActivationDTOMap.containsKey(deviceMonth)){
                    deviceActivationDTOMap.put(deviceYear,Optional.ofNullable(deviceActivationDTOMap.get(deviceMonth)).orElse(0)+1);
                }else{
                    deviceActivationDTOMap.put(deviceMonth,1);
                }
            } else if (finalType==2 && Objects.equals(finalDeviceActivationYear,deviceYear) && Objects.equals(finalDeviceActivationMonth,deviceMonth) ) {
                if(deviceActivationDTOMap.containsKey(deviceDay)){
                    deviceActivationDTOMap.put(deviceDay,Optional.ofNullable(deviceActivationDTOMap.get(deviceDay)).orElse(0)+1);
                }else{
                    deviceActivationDTOMap.put(deviceDay,1);
                }
            }
            if(1==deviceType){
                singleDeviceAmount.getAndAdd(1);
            } else if (2==deviceType) {
                doubleDeviceAmount.getAndAdd(1);
            }

        });
        //当日工作设备数量
        AtomicInteger todayWorkDeviceAmount = new AtomicInteger(0);
        //当日燃料消耗数量
        AtomicDouble todayFuelConsumption = new AtomicDouble(0.0);
        //设备运行状态
        deviceStateRecordList.parallelStream().forEach(deviceStateRecord -> {
            String stateYear = deviceStateRecord.getYear();
            String stateMonth = deviceStateRecord.getMonth();
            String stateDay = deviceStateRecord.getDay();
            Double thisOilConsumption = Optional.ofNullable(deviceStateRecord.getThisOilConsumption()).orElse(0.0);
            if(year.toString().equals(stateYear) && month.toString().equals(stateMonth) && day.toString().equals(stateDay)){
                todayWorkDeviceAmount.getAndAdd(1);
                todayFuelConsumption.getAndAdd(thisOilConsumption);


            }
        });



        //代理商排名列表
        List<AgentRankDTO> agentRankDTOList = new ArrayList<>();
        //代理商总设备台数
        AtomicInteger agentDeviceAmount = new AtomicInteger(0);
        agentList.parallelStream().forEach(agent -> {
            agentRankDTOList.add(AgentRankDTO.convert(agent));
            agentDeviceAmount.getAndAdd(Optional.ofNullable(agent.getDeviceTotalAmount()).orElse(0));
        });
        agentRankDTOList.sort(Comparator.comparing(AgentRankDTO::getAgentDeviceTotalAmount));

        //代理商今日充值金额
        Double agentTodayEcharge = 0.0;
        //充值记录
        List<TZdjdRechargeRecord> rechargeRecordList = rechargeRecordService.selectListByYearMonthDay(year, month, day);
        agentTodayEcharge = rechargeRecordList.parallelStream().mapToDouble(TZdjdRechargeRecord::getRechargeAmount).sum();


        dto.setDeviceStatusDTOList(DeviceStatusDTO.convert(deviceStatusDTOMap, deviceList.size()));
        dto.setAgentDeviceAmount(agentDeviceAmount.get());
        dto.setAgentTodayEcharge(agentTodayEcharge);
        dto.setAgentRankDTOList(agentRankDTOList);
        dto.setTodayWorkDeviceAmount(todayWorkDeviceAmount.get());
        dto.setDeviceActivationDTOList(DeviceActivationDTO.cover(deviceActivationDTOMap, type==1 ? 12 : YearMonth.of(deviceActivationYear, deviceActivationMonth).lengthOfMonth()));
        dto.setSingleDeviceAmount(singleDeviceAmount.get());
        dto.setDoubleDeviceAmount(doubleDeviceAmount.get());

        return null;
    }

}

